home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / gnuish / cpio11as / copyout.c < prev    next >
C/C++ Source or Header  |  1992-02-22  |  8KB  |  282 lines

  1. /* copyout.c - cpio copy out sub-function.
  2.    Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
  19.    This port is also distributed under the terms of the
  20.    GNU General Public License as published by the
  21.    Free Software Foundation.
  22.  
  23.    Please note that this file is not identical to the
  24.    original GNU release, you should have received this
  25.    code as patch to the official release.
  26.  
  27.    $Header: e:/gnu/cpio/RCS/copyout.c 1.1.0.2 90/09/23 23:33:23 tho Exp $
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #ifndef S_IFLNK
  34. #define lstat stat
  35. #endif
  36. #include <errno.h>
  37. #ifndef MSDOS            /* sigh, it's `volatile' !!! */
  38. extern int errno;
  39. #endif
  40. #include <fcntl.h>
  41. #ifndef MSDOS
  42. #include <sys/file.h>
  43. #endif
  44. #ifdef USG
  45. #include <time.h>
  46. #include <string.h>
  47. #else
  48. #include <sys/time.h>
  49. #include <strings.h>
  50. #endif
  51. #include "cpio.h"
  52. #include "dstring.h"
  53. #include "extern.h"
  54.  
  55. /* Write out header FILE_HDR, including the file name, to file
  56.    descriptor OUT_DES. */
  57.  
  58. void
  59. write_out_header (file_hdr, out_des)
  60.      struct cpio_header *file_hdr;
  61.      int out_des;
  62. {
  63.   if (portability_flag)
  64.     {
  65.       char ascii_header[78];
  66.  
  67.  
  68.       sprintf (ascii_header,
  69. #ifdef MSDOS
  70.            "%06ho%06ho%06ho%06ho%06ho%06ho%06ho%06ho%011lo%06ho%011lo",
  71. #else
  72.            "%06o%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o",
  73. #endif
  74.            file_hdr->h_magic & 0xFFFF, file_hdr->h_dev & 0xFFFF,
  75.            file_hdr->h_ino & 0xFFFF, file_hdr->h_mode & 0xFFFF,
  76.            file_hdr->h_uid & 0xFFFF, file_hdr->h_gid & 0xFFFF,
  77.            file_hdr->h_nlink & 0xFFFF, file_hdr->h_rdev & 0xFFFF,
  78.            file_hdr->h_mtime, file_hdr->h_namesize & 0xFFFF,
  79.            file_hdr->h_filesize);
  80.       copy_buf_out (ascii_header, out_des, 76);
  81.  
  82.       /* Write file name to output.  */
  83.       copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
  84.     }
  85.   else
  86.     {
  87.       /* Word align the output. */
  88.       if (output_size & 1)
  89.     copy_buf_out ("", out_des, 1);
  90.  
  91. #ifdef MSDOS
  92.       file_hdr->h_mtimes[0] = (unsigned int) (file_hdr->h_mtime >> 16);
  93.       file_hdr->h_mtimes[1] = (unsigned int) (file_hdr->h_mtime & 0xFFFF);
  94.  
  95.       file_hdr->h_filesizes[0]
  96.     = (unsigned int) (file_hdr->h_filesize >> 16);
  97.       file_hdr->h_filesizes[1]
  98.     = (unsigned int) (file_hdr->h_filesize & 0xFFFF);
  99. #else /* not MSDOS */
  100.       file_hdr->h_mtimes[0] = file_hdr->h_mtime >> 16;
  101.       file_hdr->h_mtimes[1] = file_hdr->h_mtime & 0xFFFF;
  102.  
  103.       file_hdr->h_filesizes[0] = file_hdr->h_filesize >> 16;
  104.       file_hdr->h_filesizes[1] = file_hdr->h_filesize & 0xFFFF;
  105. #endif /* not MSDOS */
  106.  
  107.       /* Output the file header. */
  108.       copy_buf_out ((char *) file_hdr, out_des, 26);
  109.  
  110.       /* Write file name to output.  */
  111.       copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
  112.  
  113.       /* Word align the output. */
  114.       if (file_hdr->h_namesize % 2)
  115.     copy_buf_out ("", out_des, 1);
  116.     }
  117. }
  118.  
  119. /* Read a list of file names from the standard input
  120.    and write a cpio collection on the standard output.
  121.    The format of the header depends on the compatibility (-c) flag.  */
  122.  
  123. void
  124. process_copy_out ()
  125. {
  126.   int res;            /* Result of functions.  */
  127.   dynamic_string input_name;    /* Name of file read from stdin.  */
  128.   long times[2];        /* For resetting file times after copy.  */
  129.   struct stat file_stat;    /* Stat record for file.  */
  130.   struct cpio_header file_hdr;    /* Output header information.  */
  131.   int in_file_des;        /* Source file descriptor. */
  132.   int out_file_des;        /* Output file descriptor. */
  133.  
  134. #ifdef MSDOS
  135.   setmode (fileno (stdout), O_BINARY);
  136. #endif
  137.  
  138.   /* Initialize copy out. */
  139.   ds_init (&input_name, 128);
  140.   file_hdr.h_magic = 070707;
  141.  
  142.   /* Check whether the output file might be a tape.  */
  143.   out_file_des = fileno (stdout);
  144.   if (fstat (out_file_des, &file_stat))
  145.     error (1, errno, "standard output is closed");
  146. #ifdef S_IFBLK
  147.   output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR
  148.                || (file_stat.st_mode & S_IFMT) == S_IFBLK);
  149. #else /* not S_IFBLK */
  150.   output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR);
  151. #endif /* not S_IFBLK */
  152.   output_is_seekable = ((file_stat.st_mode & S_IFMT) == S_IFREG);
  153.  
  154.   /* Copy files with names read from stdin.  */
  155.   while (ds_fgets (stdin, &input_name) != NULL)
  156.     {
  157.       /* Check for blank line.  */
  158.       if (input_name.ds_string[0] == 0)
  159.     {
  160.       error (0, 0, "blank line ignored");
  161.       continue;
  162.     }
  163.  
  164.       /* Process next file. */
  165.       if ((*xstat) (input_name.ds_string, &file_stat) < 0)
  166.     error (0, errno, "%s", input_name.ds_string);
  167.       else
  168.     {
  169.       /* Set values in output header.  */
  170.       file_hdr.h_dev = file_stat.st_dev;
  171.       file_hdr.h_ino = file_stat.st_ino;
  172.       file_hdr.h_mode = file_stat.st_mode;
  173.       file_hdr.h_uid = file_stat.st_uid;
  174.       file_hdr.h_gid = file_stat.st_gid;
  175.       file_hdr.h_nlink = file_stat.st_nlink;
  176.       file_hdr.h_rdev = file_stat.st_rdev;
  177.       file_hdr.h_mtime = file_stat.st_mtime;
  178.       file_hdr.h_filesize = file_stat.st_size;
  179.       file_hdr.h_namesize = ds_strlen (&input_name) + 1;
  180.       file_hdr.h_name = input_name.ds_string;
  181.  
  182.       /* Copy the named file to the output.  */
  183.       switch (file_hdr.h_mode & S_IFMT)
  184.         {
  185.         case S_IFREG:
  186. #ifdef MSDOS
  187.           in_file_des = open (input_name.ds_string,
  188.                   O_RDONLY | O_BINARY, 0);
  189. #else
  190.           in_file_des = open (input_name.ds_string, O_RDONLY, 0);
  191. #endif
  192.           if (in_file_des < 0)
  193.         {
  194.           error (0, errno, "%s", input_name.ds_string);
  195.           continue;
  196.         }
  197.  
  198.           write_out_header (&file_hdr, out_file_des);
  199.           copy_files (in_file_des, out_file_des, file_hdr.h_filesize);
  200.           close (in_file_des);
  201.           if (reset_time_flag)
  202.         {
  203.           times[0] = file_stat.st_atime;
  204.           times[1] = file_stat.st_mtime;
  205.           if (utime (file_hdr.h_name, times) < 0)
  206.             error (0, errno, "%s", file_hdr.h_name);
  207.         }
  208.           break;
  209.  
  210.         case S_IFDIR:
  211.           file_hdr.h_filesize = 0;
  212.           write_out_header (&file_hdr, out_file_des);
  213.           break;
  214.  
  215.         case S_IFCHR:
  216. #ifdef S_IFBLK
  217.         case S_IFBLK:
  218. #endif
  219. #ifdef S_IFSOCK
  220.         case S_IFSOCK:
  221. #endif
  222. #ifdef S_IFIFO
  223.         case S_IFIFO:
  224. #endif
  225.           file_hdr.h_filesize = 0;
  226.           write_out_header (&file_hdr, out_file_des);
  227.           break;
  228.  
  229. #ifdef S_IFLNK
  230.         case S_IFLNK:
  231.           {
  232.         char *link_name = (char *) xmalloc (file_stat.st_size);
  233.  
  234.         if (readlink (input_name.ds_string, link_name,
  235.                   file_stat.st_size) < 0)
  236.           {
  237.             error (0, errno, "%s", input_name.ds_string);
  238.             free (link_name);
  239.             continue;
  240.           }
  241.         write_out_header (&file_hdr, out_file_des);
  242.         copy_buf_out (link_name, out_file_des, file_stat.st_size);
  243.         free (link_name);
  244.           }
  245.           break;
  246. #endif
  247.  
  248.         default:
  249.           error (0, 0, "%s: unknown file type", input_name.ds_string);
  250.         }
  251.  
  252.       if (verbose_flag)
  253.         fprintf (stderr, "%s\n", input_name.ds_string);
  254.     }
  255.     }
  256.  
  257.   /* The collection is complete; append the trailer.  */
  258.   file_hdr.h_filesize = 0;
  259.   file_hdr.h_namesize = 11;
  260.   file_hdr.h_name = "TRAILER!!!";
  261.   write_out_header (&file_hdr, out_file_des);
  262.  
  263.   /* Fill up the output block.  */
  264.   while (output_size < io_block_size)
  265.     {
  266.       copy_buf_out (output_buffer, out_file_des,
  267.             (2 * output_size < io_block_size) ?
  268.             output_size : io_block_size - output_size);
  269.     }
  270.   empty_output_buffer (out_file_des);
  271.   finish_output_file ("standard output", out_file_des);
  272. #ifdef MSDOS
  273.   res = (int) (output_bytes / io_block_size);
  274. #else
  275.   res = output_bytes / io_block_size;
  276. #endif
  277.   if (res == 1)
  278.     fprintf (stderr, "1 block\n");
  279.   else
  280.     fprintf (stderr, "%d blocks\n", res);
  281. }
  282.